Skip to content

feat: /models, /agents, and /cancel slash commands with ACP configOptions#478

Merged
thepagent merged 6 commits intoopenabdev:mainfrom
chaodu-agent:feat/model-slash-command
Apr 19, 2026
Merged

feat: /models, /agents, and /cancel slash commands with ACP configOptions#478
thepagent merged 6 commits intoopenabdev:mainfrom
chaodu-agent:feat/model-slash-command

Conversation

@chaodu-agent
Copy link
Copy Markdown
Collaborator

@chaodu-agent chaodu-agent commented Apr 19, 2026

Summary

Implements /models, /agents, and /cancel Discord slash commands that bridge to ACP session config options and cancellation.

Closes #477

Slash Commands

Command Action
/models Select AI model from a dropdown (ephemeral)
/agents Select agent mode from a dropdown (ephemeral)
/cancel Cancel the current in-flight operation

How it works

/models and /agents

User: /models (or /agents)
  → OpenAB reads cached configOptions from ACP session
  → Renders Discord Select Menu with available options
  → User picks an option
  → OpenAB sends session/set_config_option (or falls back to prompt)
  → Discord message updated with "✅ Switched to X"

/cancel

User: /cancel (while bot is streaming)
  → OpenAB sends session/cancel notification to ACP agent
  → Agent aborts in-flight LLM requests and tool calls
  → User sees "🛑 Cancel signal sent."

Changes

File Change
src/acp/protocol.rs Add ConfigOption types + parse_config_options() with kiro-cli fallback
src/acp/connection.rs Cache configOptions, set_config_option() with prompt fallback, send_notification(), cancel_handle()
src/acp/pool.rs get_config_options(), set_config_option(), cancel_session() with lock-free cancel handles
src/adapter.rs pool() accessor on AdapterRouter
src/discord.rs Register /models + /agents + /cancel, interaction handlers

Backend compatibility

Backend configOptions set_config_option session/cancel
Codex (codex-acp) ✅ Standard ✅ Native ✅ Native
Kiro (kiro-cli) ⚠️ models/modes fallback ⚠️ Prompt fallback ✅ Native

Key design decisions

  • Lock-free cancel: Cancel handles (stdin + session_id) stored separately from the connection mutex to avoid deadlock during streaming
  • Thread key format: Uses "discord:<channel_id>" matching the adapter router format
  • Ephemeral responses: Select menus and cancel confirmations only visible to invoking user

Tested

  • cargo check — no errors
  • /models shows 12 models from kiro-cli
  • /agents shows 2 modes (kiro_default, kiro_planner)
  • ✅ Model/agent selection works with prompt fallback
  • /cancel stops in-flight streaming without deadlock
  • ✅ "No options available" when no session exists

Discord Discussion URL: https://discord.com/channels/1486155598964719616/1495343752947040306

@chaodu-agent chaodu-agent requested a review from thepagent as a code owner April 19, 2026 18:59
@github-actions github-actions bot added closing-soon PR missing Discord Discussion URL — will auto-close in 3 days needs-rebase pending-contributor labels Apr 19, 2026
@thepagent thepagent changed the title feat: /model slash command with ACP configOptions feat: /models and /agents slash commands with ACP configOptions Apr 19, 2026
@pahud pahud force-pushed the feat/model-slash-command branch from e771e0f to d743248 Compare April 19, 2026 19:50
@thepagent thepagent changed the title feat: /models and /agents slash commands with ACP configOptions feat: /models, /agents, and /cancel slash commands with ACP configOptions Apr 19, 2026
@thepagent
Copy link
Copy Markdown
Collaborator

The CI failure is from cargo clippy -- -D warnings on the merge commit:

warning: methods `send_notification` and `cancel_session` are never used

AcpConnection::cancel_session() and send_notification() are defined but never called — the pool's cancel_session() uses the lock-free stdin approach directly, bypassing the connection-level methods.

This only surfaces when merged with main (the branch itself compiles clean). Fix options:

  1. Rebase onto main and add #[allow(dead_code)] on send_notification and cancel_session in connection.rs (keeps them as public API for future use)
  2. Or remove them — the pool's lock-free cancel is the only path used

The branch needs a rebase regardless (needs-rebase label) since it's based on v0.6.4.

@thepagent
Copy link
Copy Markdown
Collaborator

CI fix: rebase required

The cargo clippy -- -D warnings failure is:

warning: methods `send_notification` and `cancel_session` are never used
  --> src/acp/connection.rs:293:18

Root cause: The branch is based on v0.6.4 — the GitHub merge commit creates these methods but nothing calls them because pool.cancel_session() uses the lock-free stdin approach directly.

Attempted rebase: connection.rs conflicts are trivial (both-sides field additions), but discord.rs has diverged too much between v0.6.4 and current main (different imports, struct patterns, handler signatures). A mechanical rebase won't work.

Fix needed: Rewrite the PR against current main (openab-0.7.8-beta.7). The core logic (configOptions parsing, slash command handlers, cancel handles) is solid — it just needs to be applied to the current codebase structure.

Alternatively, add #[allow(dead_code)] on send_notification and cancel_session in connection.rs if you want to keep them as public API for future use.

@chaodu-agent chaodu-agent force-pushed the feat/model-slash-command branch 3 times, most recently from c163e00 to 4819566 Compare April 19, 2026 21:48
@thepagent thepagent removed the closing-soon PR missing Discord Discussion URL — will auto-close in 3 days label Apr 19, 2026
Copy link
Copy Markdown
Collaborator

@thepagent thepagent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — clean rebase, much simpler than the previous version.

✅ configOptions parsing + caching on create/load
✅ ConfigUpdate event keeps cache fresh during streaming
✅ Pool lock ordering correct (drop state before locking connection)
✅ Ephemeral responses, select menu with current value pre-selected
✅ No dead code — previous send_notification/cancel_session removed

Notes:

  • set_config_option will error for backends that don't support it (kiro-cli). Previous version had a prompt fallback — acceptable to omit if codex-acp is the primary target, but worth documenting.
  • docs/slash-commands.md references /models, /agents, /cancel but this revision only implements /model. I'll push a fix to align the docs.

@thepagent thepagent force-pushed the feat/model-slash-command branch from 4819566 to ce98b19 Compare April 19, 2026 22:16
@github-actions github-actions bot added the closing-soon PR missing Discord Discussion URL — will auto-close in 3 days label Apr 19, 2026
@thepagent thepagent force-pushed the feat/model-slash-command branch 2 times, most recently from a5b7680 to 3516efa Compare April 19, 2026 22:19
@chaodu-agent chaodu-agent force-pushed the feat/model-slash-command branch from 3516efa to 603bcac Compare April 19, 2026 22:21
Implements dynamic model selection via Discord slash command that bridges
to ACP session/set_config_option.

Flow:
1. Bot registers /model slash command on ready
2. User invokes /model → OpenAB reads cached configOptions (category: model)
3. Discord Select Menu rendered with available models
4. User selects → OpenAB sends session/set_config_option to ACP agent
5. Agent confirms → Discord message updated

Changes:
- protocol.rs: Add ConfigOption/ConfigOptionValue types + parse_config_options()
- connection.rs: Cache configOptions on session_new, add set_config_option()
- pool.rs: Expose get_config_options() and set_config_option() on SessionPool
- discord.rs: Register /model command in ready(), handle interaction_create()
  for both slash commands and component select menus

Closes openabdev#477
@chaodu-agent chaodu-agent force-pushed the feat/model-slash-command branch 2 times, most recently from 3f52c10 to de38dba Compare April 19, 2026 22:25
- /agents: select agent mode (category: agent) via generic handle_config_command
- /cancel: send session/cancel notification to abort in-flight operations
- Refactor handle_model_command into generic handle_config_command(category, label)
- Add pool.cancel_session() using send_raw for JSON-RPC notification
- Make AcpConnection::send_raw pub for pool cancel access
@thepagent thepagent force-pushed the feat/model-slash-command branch from de38dba to 115634f Compare April 19, 2026 22:26
Store cancel handles (stdin + session_id) separately in PoolState.
cancel_session() writes directly to stdin without locking the
connection, so it works even while the streaming loop holds the
connection lock.
@github-actions github-actions bot removed the closing-soon PR missing Discord Discussion URL — will auto-close in 3 days label Apr 19, 2026
- parse_config_options: fall back to kiro models/modes format when
  configOptions is absent
- set_config_option: fall back to sending /<config_id> <value> as
  prompt when session/set_config_option is not supported
- Tighten send_raw to pub(crate)
@thepagent thepagent merged commit b788e37 into openabdev:main Apr 19, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Dynamic model selection via ACP configOptions + Discord slash command

2 participants